//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//
/*++
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.
Copyright (c) 1995-1999  Microsoft Corporation

Module Name:

response.h

Abstract:


Notes:


--*/
/*
------------------------------------------------------------------------------
    Revision History
    Date                      Author                  Activity ID                    Activity Headline
    2006-02-09            Wangxiaogang        CEDB00006280              Move RIL from public to bsp270
    2007-04-26            qinxuetao           WM600002433               Add +TEDGE to get the access technology
    2007-06-07            qinxuetao           WM600003908               Can't enter STK main menu after bootup
    2007-06-21            qinxuetao           WM600007125               Change STK and PB init procedure
    2007-08-14            qinxuetao           WM600009403               Only init STK after some delay since phone on
------------------------------------------------------------------------------
*/

#pragma once

// Used by CResponse
#define ALLOC_SIZE                      1024

extern CRITICAL_SECTION g_csDeactCringLock;
extern bool g_fCringRcvd;
extern DWORD g_LastCringRcvd;
// The constant below is part of a heuristic used in the RIL driver which does not track calls.
// The value of this constant needs to be tuned based on how frequently the radio sends CRING notifications
// for a call not yet accepted, the lower this frequency the higher this value should be. However, making
// this too long will have the undesirable side effect of ignoring the celltsp's deactivate request after a
// very quick voice call (ring -> accept -> hangup -> deactivate is all within the time below)
#define STALE_CRING_THRESHOLD 5000 // in ms
inline bool IncomingCallInProgress(void)
{
    return (g_fCringRcvd && ((GetTickCount() - g_LastCringRcvd) < STALE_CRING_THRESHOLD));
}


//
// Error mapping structure used for binary search
//
struct ERRORMAP {
    HRESULT hrError;
    DWORD dwCode;
};

inline void *AllocBlob(UINT bytes)
{
    return (void *)LocalAlloc(LMEM_MOVEABLE,bytes);
}

inline void *FreeBlob(void *pblob)
{
    return (void *)LocalFree(pblob);
}

inline void *ReallocBlob(void *pblob, UINT bytes)
{
    if (!pblob)
    {
        return (void *)LocalAlloc(LMEM_MOVEABLE,bytes);
    }

    return (void *)LocalReAlloc(pblob,bytes,LMEM_MOVEABLE);
}

//
// AT command response
//
class CResponse : public CBuffer
{
public:
            CResponse();
            ~CResponse();
            CResponse(const CResponse &Rsp);

    BOOL    AppendString(const LPCSTR szString, const UINT cbString, LPCSTR& rszRemainder, UINT& rcbRemainde, BOOL fDataOnNotificationPort);
    BOOL    SetBlob(const void* const pBlob, const UINT cbBlob);
    BOOL    MakeError(const HRESULT hr);
    void    DeleteBlob()                                { FreeBlob(m_pBlob); m_pBlob = NULL; m_cbBlob = 0; };
    void    MakeOK()                                    { m_dwCode = RIL_RESULT_OK; m_fUnsolicited = FALSE; };
    BOOL    ParseOKData(CCommand*&rpCmd);
    HRESULT GetError() const;
    void    GetBlob(void*& rpBlob, UINT& rcbBlob) const { rpBlob = m_pBlob; rcbBlob = m_cbBlob; };
    DWORD   GetNotifyCode() const                       { return m_dwCode; };
    BOOL    FUnsolicited() const                        { return !!m_fUnsolicited; };
    BOOL    FUnrecognized() const                       { return !!m_fUnrecognized; };
#ifdef OEM2_DRIVER
    BOOL    FCPINNRsp();
#endif
    void    ConnectToOK()   { DEBUGCHK(RIL_NOTIFY_CONNECT == m_dwCode);   m_dwCode = RIL_RESULT_OK; m_fUnsolicited = FALSE; };
    void    NoCarrierToOK() { DEBUGCHK(RIL_RESULT_NOCARRIER == m_dwCode); m_dwCode = RIL_RESULT_OK; m_fUnsolicited = FALSE; };
    void    OKToNoCarrier() { DEBUGCHK(RIL_RESULT_OK == m_dwCode); m_dwCode = RIL_RESULT_NOCARRIER; m_fUnsolicited = FALSE; };
    void    SetCallAborted() { m_dwCode = RIL_RESULT_CALLABORTED; m_fUnsolicited = FALSE; };
    BOOL    OKToError(HRESULT hr);
    void    SetPotentialBogusResponseFlag() { m_fPotentialBogusResponse = TRUE; }
    BOOL    UpdateDataPointer(UINT nOffset);

private:
    BOOL    Parse(UINT& rcbNewLength, BOOL fDataOnNotificationPort);
    BOOL    ParseOKOrError(const BOOL fOK, UINT& rcbNewLength);
    BOOL    ParseNotification(UINT& rcbNewLength, BOOL fDataOnNotificationPort);
    BOOL    ParseV25Response(UINT nResponseCode);
    BOOL    ParseExtError(LPCSTR& rszPointer, const ERRORMAP* const rgemMap, const UINT nMapEntries, UINT &nCode, BOOL fSigned);
    BOOL    ParseExtRing(LPCSTR& rszPointer);
    BOOL    ParseServiceInfo(LPCSTR& rszPointer);
    BOOL    ParseRemotePartyInfo(LPCSTR& rszPointer, BOOL fCLIP);
    BOOL    ParseCallWaitingInfo(LPCSTR& rszPointer);
    BOOL    ParseUnsolicitedSSInfo(LPCSTR& rszPointer);
    BOOL    ParseIntermediateSSInfo(LPCSTR& rszPointer);
    BOOL    ParseCallMeter(LPCSTR& rszPointer);
    BOOL    ParseCallProgressInformation(LPCSTR& rszPointer);
    BOOL    ParseRegistrationStatus(LPCSTR& rszPointer, DWORD const dwNotifyCode);
#ifdef EMP_DRIVER
    BOOL    ParseExtRegistrationStatus(LPCSTR& rszPointer);
    BOOL    ParseIndicatorEvent(LPCSTR& rszPointer);
#elif defined(WAVECOM_DRIVER)
    BOOL    ParseExtRegistrationStatus(LPCSTR& rszPointer);
#endif
    BOOL    ParseHSCSDParams(LPCSTR& rszPointer);
    BOOL    ParseUSSDInfo(LPCSTR& rszPointer);
    BOOL    ParseMessage(LPCSTR& rszPointer, DWORD const dwNotifyCode);
    BOOL    ParseMessageInSim(LPCSTR& rszPointer, DWORD const dwNotifyCode);
    BOOL    ParseCPIN(LPCSTR& rszPointer);
    BOOL    ParseSTIN(LPCSTR& rszPointer); 
    BOOL    SimtkitCommandTransfer(UINT nSourceCmd, DWORD & dwDestCmd);  //Add by zxn
#ifdef OEM2_SIMTOOLKIT
    BOOL    ParseSTC(LPCSTR& rszPointer);
#endif
    BOOL    ParseSIMToolkitCmdOrRsp(LPCSTR& rszPointer, const DWORD dwNotifyCode);
    BOOL    ParseSIMToolkitCallSetup(LPCSTR& rszPointer);
    void    ParseJunk(UINT nCRLFs, LPCSTR& rszPointer);
    BOOL    ParsePartialResponse(UINT& rcbNewLength);
    HRESULT SendSIMToolkitErrorRsp(RILSIMTOOLKITCMD* pCmd);
    //sunrenhong add for charge
    BOOL  Parsecharge(LPCSTR szRsp, LPCSTR& rszPointer);

    DWORD   m_dwCode;
    void*   m_pBlob;
    UINT    m_cbBlob;
    DWORD   m_fUnsolicited : 1;
    DWORD   m_fUnrecognized : 1;
    DWORD   m_fPotentialBogusResponse : 1;
    UINT    m_nOffset;
};


//
// Notification data
//
class CNotificationData
{
public:
                        CNotificationData();
                        ~CNotificationData();

    BOOL                InitFromDWORDBlob(const DWORD dwCode, const DWORD dwBlob);
    BOOL                InitFromRealBlob(const DWORD dwCode, const void* const pBlob, UINT cbBlob);
    BOOL                FinishInitFromRspBlob(const CResponse& rRsp);
    BOOL                DelayInitFromRspBlob(const DWORD dwCode);

    BOOL                FDelayedInitFromRsp() const { return !!m_fDelayedInitFromRsp; };
    DWORD               GetCode() const             { DEBUGCHK(FALSE != !!m_fInited); return m_dwCode; };
    const void* const   GetBlob() const             { DEBUGCHK(FALSE != !!m_fInited); return m_pBlob; };
    UINT                GetSize() const             { DEBUGCHK(FALSE != !!m_fInited); return m_cbBlob; };

private:
    DWORD       m_dwCode;
    void*       m_pBlob;
    UINT        m_cbBlob;
    DWORD       m_fInited : 1;
    DWORD       m_fDelayedInitFromRsp : 1;
};

extern void StartPlmnNameRead();
#ifdef RIL_ENABLE_EONS
extern void StartEONSRead();
#endif
BOOL IsSTKReady();

#if defined(OEM1_CSQ_NOTIFICATION) || defined(OEM2_DRIVER) || defined(EMP_DRIVER) || defined(WAVECOM_DRIVER)
extern RILSIGNALQUALITY g_rsq;
extern BOOL g_fSignalQualityReceived;
#endif

#if defined(EMP_DRIVER) || defined(WAVECOM_DRIVER)
extern BOOL g_fSystemChanged;
extern DWORD g_dwSystemType;
extern DWORD g_dwSystemCaps;
#endif

#ifdef WAVECOM_DRIVER
extern BOOL g_bSIMPBReady;
#endif

